文章目录
  1. 1. The extend Function

The extend Function

1
2
3
4
5
6
7
/* Extend function. */
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
}

It sets the prototype and then resets the correct constructor. As a bonus, it adds the empty class F into the prototype chain in order to prevent a new (and possible large) instance of the superclass from having to be instantiated. This is also beneficial in situations where the superclass’s constructor has side effects or does something that is computationally intensive. Since the object that gets instantiated for the prototype is usually just a throwaway instance, you don’t want to create it unnecessarily

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* Class Person. */
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
/* Class Author. */
function Author(name, books) {
Person.call(this, name);
this.books = books;
}
extend(Author, Person);
Author.prototype.getBooks = function() {
return this.books;
};

Instead of setting the prototype and constructor attributes manually, simply call the extend function immediately after the class declaration (and before you add any methods to the prototype). The only problem with this is that the name of the superclass (Person) is hardcoded within the Author declaration. It would be better to refer to it in a more general way:

1
2
3
4
5
6
7
8
9
10
11
/* Extend function, improved. */
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}

This version is a little longer but provides the superclass attribute, which you can now use to make Author less tightly coupled to Person. The first four lines of the function are the same as before. The last three lines simply ensure that the constructor attribute is set correctly on the superclass (even if the superclass is the Object class itself). This will become important when you use this new superclass attribute to call the superclass’s constructor:

1
2
3
4
5
6
7
8
9
/* Class Author. */
function Author(name, books) {
Author.superclass.constructor.call(this, name);
this.books = books;
}
extend(Author, Person);
Author.prototype.getBooks = function() {
return this.books;
};

Adding the superclass attribute also allows you to call methods directly from the superclass.This is useful if you want to override a method while still having access to the superclass’s implementation of it. For instance, to override Person’s implementation of getName with a new version,you could use Author.superclass.getName to first get the original name and then add to it:

1
2
3
4
Author.prototype.getName = function() {
var name = Author.superclass.getName.call(this);
return name + ', Author of ' + this.getBooks().join(', ');
};
文章目录
  1. 1. The extend Function